package com.yuyou.fn.common.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by wens on 16-7-22.
 */
public class TimeUtils {

    public static XMLGregorianCalendar dateToXmlDate(Date date){
        if (date==null){
            date=TimeUtils.now();
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        DatatypeFactory dtf = null;
        try {
            dtf = DatatypeFactory.newInstance();
        } catch (DatatypeConfigurationException e) {
        }
        XMLGregorianCalendar dateType = dtf.newXMLGregorianCalendar();
        dateType.setYear(cal.get(Calendar.YEAR));
        //由于Calendar.MONTH取值范围为0~11,需要加1
        dateType.setMonth(cal.get(Calendar.MONTH)+1);
        dateType.setDay(cal.get(Calendar.DAY_OF_MONTH));
        dateType.setHour(cal.get(Calendar.HOUR_OF_DAY));
        dateType.setMinute(cal.get(Calendar.MINUTE));
        dateType.setSecond(cal.get(Calendar.SECOND));
        return dateType;
    }


    /**
    *@Description:
    *@Param: startTime(08:00),endTime(09:00)
    *@return:
    *@Author: lzh
    *@date:
    */
    public static int countMinByTimeStr(String startTime,String endTime){
        if (StringUtils.isEmpty(startTime)|| StringUtils.isEmpty(endTime)){
            return 0;
        }
        String[] sa=startTime.split(":");
        String[] sg=endTime.split(":");
        int min=(Integer.parseInt(sg[0])*60+Integer.parseInt(sg[1]))-(Integer.parseInt(sa[0])*60+Integer.parseInt(sa[1]));
        return min;
    }

    public static String prettyTime(long off) {

        off = off / 1000;
        if (off < 60) {
			return off + "秒";
        }

        off = off / 60;

        if (off < 60) {
			return off + "分钟";
        }

        off = off / 60;

        if (off < 24) {
			return off + "小时";
        }

		return off / 24 + "天";


    }

    public static Date now() {
        return new Date();
    }

    public static Date nowDate(){
        Calendar instance = Calendar.getInstance();
        instance.set(Calendar.MILLISECOND,0);
        instance.set(Calendar.SECOND,0);
        instance.set(Calendar.MINUTE,0);
        instance.set(Calendar.HOUR_OF_DAY,0);
        return instance.getTime() ;
    }

    /**
	 * 时间转换格式
	 * 
	 * @param date
	 * @return
	 */
    public static String date2String(Date date) {
        if(date != null) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String strDate = sdf.format(date);
            return strDate;
        }
        return null;
    }

    public static String date2String(Date date ,String format) {
        if(date != null) {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            String strDate = sdf.format(date);
            return strDate;
        }
        return null;
    }

    public static Date parse(String src, String format)  {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            return sdf.parse(src) ;
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

	/* 两个日期相隔天数 */
    public static int daysOfTwo(Date fDate, Date oDate)  {

        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        try {
            fDate=sdf.parse(sdf.format(fDate));
            oDate=sdf.parse(sdf.format(oDate));
        }catch (Exception e){

        }

        Calendar cal = Calendar.getInstance();
        cal.setTime(fDate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(oDate);
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*3600*24);
        return Integer.parseInt(String.valueOf(between_days));
    }


    /**
	 * 获取当前日期是星期几<br>
	 *
	 * @param dt
	 * @return 当前日期是星期几
	 */
    public static int getWeekOfDate(Date dt) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;
        return  w;
    }

    public static boolean isOverlap(String startdate1, String enddate1,String startdate2, String enddate2,String timeFormat) {
        SimpleDateFormat format = new SimpleDateFormat(timeFormat);
        Date leftStartDate = null;
        Date leftEndDate = null;
        Date rightStartDate = null;
        Date rightEndDate = null;
        try {
            leftStartDate = format.parse(startdate1);
            leftEndDate = format.parse(enddate1);
            rightStartDate = format.parse(startdate2);
            rightEndDate = format.parse(enddate2);
        } catch (ParseException e) {
            return false;
        }
        return        ((leftStartDate.getTime() >= rightStartDate.getTime()) && leftStartDate.getTime() < rightEndDate.getTime())
                        || ((leftStartDate.getTime() > rightStartDate.getTime())
                                && leftStartDate.getTime() <= rightEndDate.getTime())
                        ||
                        ((rightStartDate.getTime() >= leftStartDate.getTime())
                                && rightStartDate.getTime() < leftEndDate.getTime())
                        ||
                        ((rightStartDate.getTime() > leftStartDate.getTime())
                                && rightStartDate.getTime() <= leftEndDate.getTime());

    }

	// 给定两个日期（string），遍历之间的所有日期
    public static List<String> queryData(String startAt, String endAt) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<String> dates = new ArrayList<>();
        try {
            Date startDate = dateFormat.parse(startAt);
            Date endDate = dateFormat.parse(endAt);
            dates.addAll(queryData(startDate, endDate));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return dates;
    }

    public static List<String> queryData(Date startAt, Date endAt) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<String> dates = new ArrayList<>();
        Calendar start = Calendar.getInstance();
        start.setTime(startAt);
        Calendar end = Calendar.getInstance();
        end.setTime(endAt);
        while (start.before(end) || start.equals(end)) {
            dates.add(dateFormat.format(start.getTime()));
            start.add(Calendar.DAY_OF_YEAR, 1);
        }
        return dates;
    }

    public static BigDecimal hoursCounting(String startDate, String endDate, String startTime, String endTime,String dateFormat,String timeFormat) {
        Date date1 = parse(startDate, dateFormat);
        Date date2 = parse(endDate, dateFormat);
        BigDecimal hours1 = hoursOfTwo(date1, date2);
        Date time1 = parse(startTime, timeFormat);
        Date time2 = parse(endTime, timeFormat);
        BigDecimal hours2 = hoursOfTwo(time1,time2);
        return hours1.add(hours2);
    }

	// 相隔小时数
    private static BigDecimal hoursOfTwo(Date time1, Date time2) {

        long diff = time2.getTime() - time1.getTime();
        BigDecimal hours = new BigDecimal(diff).divide(new BigDecimal(3600000),2,BigDecimal.ROUND_HALF_UP);
        return hours;
    }

	/**
	 * 时间运算
	 * 
	 * @param date
	 *            时间
	 * @param field
	 *            需要加减的属性
	 */
	public static Date operation(Date date, int field, int amount) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(field, amount);
		return calendar.getTime();
	}

	public static BigDecimal countHourNum(String startStr,String endStr){
        Date start=Utils.parseDate(startStr,"HH:mm");
        Date end=Utils.parseDate(endStr,"HH:mm");
        BigDecimal result= BigDecimals.toFixed2(new BigDecimal((double)(end.getTime()-start.getTime())/1000/60/60),2);
        return result;
	}

    public  static  void main(String[] art) throws  Exception{

        String urlParams= URLEncoder.encode("areaTeamId="+123+"&periodIds="+ StringUtils.join(Arrays.asList(1,3,4),",")+"&gradeIds="+StringUtils.join(Arrays.asList(1,3,4),","));
        String aga="22221";
        String tta=aga.substring(0,3);
	    Date tafa=TimeUtils.now();

        List<Long> sd=new ArrayList<>();
	    sd.add(1L);
	    sd.add(2L);
	    if (sd.contains(1l)){
	        System.out.println("sdfdsf");
        }

	    String stal="08:00";
	    String as="09:40";
	    BigDecimal sssaga=countHourNum(stal,as);



        int days1r5=daysOfTwo(new Date(),new Date());
	    Integer agat=7;
	    Integer agahh=1;
	    agahh=agahh/agat +agahh%agat;

	    List<String> afa=new ArrayList<>();
	    afa.add("a");
	    afa.add("b");
        List<String> afa1=new ArrayList<>();
        afa1.add("a");
        afa1.add("b1");

        List<String> agage=afa;
        agage.retainAll(afa1);

        String ssl1="2017-02-28";
        Date dates=Utils.parseDate(ssl1,"yyyy-MM-dd");

        Date saga= addYearByNum(dates,1);

	    BigDecimal tsth=BigDecimal.ZERO;
	    if (tsth.equals(BigDecimal.ZERO)){
	        System.out.println("fsd");
        }

	    String ssl="2016";
	    String ss2="2019";
	    Integer inte=Integer.parseInt(ss2);
	    Integer ssssf=Integer.parseInt(ssl);
	    while (ssssf<=inte){
	        System.out.println(ssssf.toString());
            ssssf=ssssf+1;
        }
        System.exit(0);



	    int days=daysOfTwo(new Date(),new Date());

	    BitSet ts=new BitSet();
	    ts.set(20,100);
        System.out.println(ts.toString());
	    BitSet ss=(BitSet) ts.clone();
        ts.set(100,120);
        System.out.println(ts.toString());
        System.out.println(ss.toString());

	    String test1="2017-09-02 24:00";
	    Date ddddd=Utils.parseDate(test1,"yyyy-MM-dd HH:mm");
	    System.out.print(toMini(ddddd));


	    String test2="2017-09-19";
	    String test3="2017-09-19";
	    String test4="2017-10-28";
	    String test6="2014-09-01";
	    String test7="2017-10-28";
	    BitSet bitSettest=new BitSet();
	    bitSettest.set(TimeUtils.toMini(Utils.parseDate(test1,"yyyy-MM-dd")),TimeUtils.toMini(Utils.parseDate(test2,"yyyy-MM-dd")));
        bitSettest.set(TimeUtils.toMini(Utils.parseDate(test3,"yyyy-MM-dd")),TimeUtils.toMini(Utils.parseDate(test4,"yyyy-MM-dd")));


        BitSet bitSet=new BitSet();
        bitSet.set(TimeUtils.toMini(Utils.parseDate(test6,"yyyy-MM-dd")),TimeUtils.toMini(Utils.parseDate(test7,"yyyy-MM-dd")));

        System.out.println(bitSet.cardinality());
        bitSet.andNot(bitSettest);
        System.out.println(bitSet.cardinality());


        String s1 = "2017-08-02 12:33:01";
	    String s2 = "2017-08-02 13:33:00";

    }

    public static String getLastDayOfMonth(int year,int month)
    {
        Calendar cal = Calendar.getInstance();
		// 设置年份
        cal.set(Calendar.YEAR,year);
		// 设置月份
        cal.set(Calendar.MONTH, month-1);
		// 获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
		// 设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
		// 格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String lastDayOfMonth = sdf.format(cal.getTime());

        return lastDayOfMonth;
    }
    public static Date changeDateByNum(Date date, int num) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DAY_OF_MONTH, num);
        return cal.getTime();
    }
    class Test<T>{
	    private   T one;

    }

    public static boolean isOverlap(Date startDate1, Date endDate1,Date startDate2, Date endDate2) {
        Date leftStartDate = startDate1;
        Date leftEndDate = endDate1;
        Date rightStartDate = startDate2;
        Date rightEndDate = endDate2;

        return        ((leftStartDate.getTime() >= rightStartDate.getTime()) && leftStartDate.getTime() < rightEndDate.getTime())
                || ((leftStartDate.getTime() > rightStartDate.getTime())
                && leftStartDate.getTime() <= rightEndDate.getTime())
                ||
                ((rightStartDate.getTime() >= leftStartDate.getTime())
                        && rightStartDate.getTime() < leftEndDate.getTime())
                ||
                ((rightStartDate.getTime() > leftStartDate.getTime())
                        && rightStartDate.getTime() <= leftEndDate.getTime());

    }

    public static int  toMini(Date date){
        return (int)( date.getTime()/1000/60  - 23667360l/*2015-01-01*/ ) ;
    }

    public static String   miniRevert(Integer timeStamp){
        Long realTimeStamp=(timeStamp.longValue()+24720000l)*60*1000;
        Date date=new Date();
        date.setTime(realTimeStamp);
        return  Utils.formatDate(date,"yyyy-MM-dd HH:mm");
    }


    public static Date startOfDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY , 0 );
        calendar.set(Calendar.MINUTE , 0 );
        calendar.set(Calendar.SECOND , 0 );
        calendar.set(Calendar.MILLISECOND , 0 );
        return calendar.getTime();
    }

    public static Date endOfDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY , 23 );
        calendar.set(Calendar.MINUTE , 59 );
        calendar.set(Calendar.SECOND , 59 );
        return calendar.getTime();
    }

    public static int durationOfDay(Date d1, Date d2) {

        if(d1.after(d2)){
            Date t  =  d1 ;
            d1 = d2 ;
            d2 = t ;
        }

        int cnt  = 1 ;

        while (!DateUtils.isSameDay(d1,d2)){
            cnt++ ;
            d1 = DateUtils.addDays(d1 , 1 );
        }
        return cnt ;
    }

    public static Date firstDateOfMonth(Date date){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DAY_OF_MONTH,1);
        Date startDate=c.getTime();
        return startDate;
    }
    public static Date lastDateOfMonth(Date date){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date endTime=c.getTime();
        return endTime;
    }

    public static Date addHourByNum(Date date,int hourNum){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR,hourNum);
        return calendar.getTime();
    }

    public static  Date addMonthByNum(Date date, int monthNum){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MONTH,monthNum);
        return c.getTime();
    }

    public static Date addYearByNum(Date date, int yearNum){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.YEAR,yearNum);
        return c.getTime();
    }

    public static Date changeOneDateLastTime(Date date) {
        String str=Utils.formatDate(date,"yyyy-MM-dd")+" 23:59:59";
        return Utils.parseDate(str,"yyyy-MM-dd HH:mm:ss");
    }

    public static Date changeSecond(Date date,int secondNum) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.SECOND,secondNum);
        return c.getTime();
    }

    public static Date changeMonth(Date date,int monthNum) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MONTH,monthNum);
        return c.getTime();
    }

    public static Date changeMinute(Date date,int minuteNum) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE,minuteNum);
        return c.getTime();
    }
}
